package com.whmskj.xjlhbc.service.impl;

import com.whmskj.xjlhbc.domain.Bcsc16SecurityReport;
import cn.dev33.satoken.stp.StpUtil;
import com.whmskj.xjlhbc.mapper.SecurityReportMapper;
import com.whmskj.xjlhbc.service.SecurityReportService;
import com.whmskj.xjlhbc.service.IPersonnelManagementDataSheetsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;

@Service
public class SecurityReportServiceImpl implements SecurityReportService {

    @Resource
    private SecurityReportMapper mapper;

    @Resource
    private IPersonnelManagementDataSheetsService personnelService;

    @Override
    public Long create(Bcsc16SecurityReport payload) {
        Bcsc16SecurityReport e = payload == null ? new Bcsc16SecurityReport() : payload;
        // 校验日期必须为今天
        LocalDate today = LocalDate.now();
        if (e.getDateport() == null) e.setDateport(today);
        if (!today.equals(e.getDateport())) {
            throw new IllegalArgumentException("日期必须为今天");
        }
        // 校验与序列化图片对象数组（1-3张，仅 url 必填，其它字段可有可无）
        java.util.List<java.util.Map<String,Object>> photos = e.getPhotos();
        if (photos == null || photos.size() < 1 || photos.size() > 3) {
            throw new IllegalArgumentException("现场图片数量需为1-3张");
        }
        // 仅校验 url 存在且格式正确；其他字段若存在则保留
        for (java.util.Map<String,Object> p : photos) {
            if (p == null) throw new IllegalArgumentException("图片对象不能为空");
            Object url = p.get("url");
            if (url == null || String.valueOf(url).trim().isEmpty()) {
                throw new IllegalArgumentException("图片url必填");
            }
            String us = String.valueOf(url).trim();
            if (!isValidUrl(us)) {
                throw new IllegalArgumentException("图片url格式错误");
            }
            // 归一化去空白
            p.put("url", us);
        }
        try {
            e.setOnsite(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(photos));
        } catch (Exception ex) {
            throw new IllegalArgumentException("现场图片格式错误");
        }
        if (e.getReporter() == null || e.getReporter().trim().isEmpty()) {
            try {
                if (StpUtil.isLogin()) {
                    String userId = StpUtil.getLoginIdAsString();
                    String nick = personnelService.getCorpMemberByLogin().getNick();
                    e.setReporter((nick != null && !nick.trim().isEmpty()) ? nick : userId);
                }
            } catch (Exception ignored) {}
        }
        if (e.getAmount() != null && e.getAmount().signum() > 0) {
            e.setAmount(e.getAmount().negate());
        }
        // 默认确认状态
        if (e.getConfirmedStatus() == null || e.getConfirmedStatus().trim().isEmpty()) {
            e.setConfirmedStatus("待确认");
        }
        e.setSubtime(LocalDateTime.now());
        mapper.insert(e);
        return e.getId();
    }

    @Override
    public Bcsc16SecurityReport detail(Long id) {
        return mapper.selectById(id);
    }


    @Override
    public List<Bcsc16SecurityReport> listHistory(String reporter, int offset, int limit) {
        return mapper.listHistoryByReporter(reporter, offset, limit);
    }



    @Override
    public List<String> listSectors() {
        return mapper.listSectorNames();
    }

    private static boolean isValidUrl(String url) {
        try {
            java.net.URI u = new java.net.URI(url);
            String scheme = u.getScheme();
            return scheme != null && ("http".equalsIgnoreCase(scheme) || "https".equalsIgnoreCase(scheme))
                    && u.getHost() != null;
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public int update(Bcsc16SecurityReport entity) {
        if (entity == null || entity.getId() == null) return 0;
        Bcsc16SecurityReport db = mapper.selectById(entity.getId());
        if (db == null) return 0;
        LocalDate today = LocalDate.now();
        // 以提交时间(subtime)的日期作为当日限制依据，避免通过修改dateport绕过
        if (db.getSubtime() == null || !today.equals(db.getSubtime().toLocalDate())) {
            throw new IllegalArgumentException("仅可操作当日记录");
        }
        // 禁止修改不可变字段，防止通过更新把昨日记录改成今日
        entity.setDateport(null);
        entity.setReporter(null);
        entity.setSubtime(null);
        // 图片对象数组校验与序列化（若传，1-3张，仅校验 url）
        java.util.List<java.util.Map<String,Object>> photos = entity.getPhotos();
        if (photos != null) {
            if (photos.size() < 1 || photos.size() > 3) {
                throw new IllegalArgumentException("现场图片数量需为1-3张");
            }
            for (java.util.Map<String,Object> p : photos) {
                if (p == null) throw new IllegalArgumentException("图片对象不能为空");
                Object url = p.get("url");
                if (url == null || String.valueOf(url).trim().isEmpty()) {
                    throw new IllegalArgumentException("图片url必填");
                }
                String us = String.valueOf(url).trim();
                if (!isValidUrl(us)) {
                    throw new IllegalArgumentException("图片url格式错误");
                }
                p.put("url", us);
            }
            try {
                entity.setOnsite(new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsString(photos));
            } catch (Exception ex) {
                throw new IllegalArgumentException("现场图片格式错误");
            }
        }
        if (entity.getAmount() != null && entity.getAmount().signum() > 0) {
            entity.setAmount(entity.getAmount().negate());
        }
        return mapper.updateById(entity);
    }



    @Override
    public int delete(Long id) {
        if (id == null) return 0;
        Bcsc16SecurityReport db = mapper.selectById(id);
        if (db == null) return 0;
        LocalDate today = LocalDate.now();
        // 删除也以提交时间(subtime)判断是否为当日
        if (db.getSubtime() == null || !today.equals(db.getSubtime().toLocalDate())) {
            throw new IllegalArgumentException("仅可操作当日记录");
        }
        return mapper.deleteById(id);
    }

}


